﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWrapper
{
    public class PingResult
    {
        [DllImport("c_wrapper.dll", EntryPoint = "create_ping_result_instance")]
        private static extern int create_ping_result_instance(ref IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "destroy_ping_result_instance")]
        private static extern void destroy_ping_result_instance(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "copy_ping_result_instance")]
        private static extern void copy_ping_result_instance(IntPtr srcinstance, IntPtr dstinstance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_all_packet")]
        private static extern int get_ping_result_all_packet(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_lost_packet")]
        private static extern int get_ping_result_lost_packet(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_max_delay_time")]
        private static extern double get_ping_result_max_delay_time(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_min_delay_time")]
        private static extern double get_ping_result_min_delay_time(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_avg_delay_time")]
        private static extern double get_ping_result_avg_delay_time(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_ping_result_eval_value")]
        private static extern double get_ping_result_eval_value(IntPtr instance);

        private IntPtr native_instance_;

        public PingResult()
        {
            create_ping_result_instance(ref native_instance_);
        }

        ~PingResult()
        {
            destroy_ping_result_instance(native_instance_);
        }

        internal IntPtr NativeInstance
        {
            get { return native_instance_; }
            set { native_instance_ = value; }
        }

        internal void CopyNativeInstance(IntPtr native_instance)
        {
            copy_ping_result_instance(native_instance, native_instance_);
        }

        public int AllSendPacket()
        {
            return get_ping_result_all_packet(native_instance_);
        }

        public int LostPacket()
        {
            return get_ping_result_lost_packet(native_instance_);
        }

        public double MaxDelayTime()
        {
            return get_ping_result_max_delay_time(native_instance_);
        }

        public double MinDelayTime()
        {
            return get_ping_result_min_delay_time(native_instance_);
        }

        public double AvgDelayTime()
        {
            return get_ping_result_avg_delay_time(native_instance_);
        }

        public double EvlValue()
        {
            return get_ping_result_eval_value(native_instance_);
        }
    }

    public class ProxyOptions
    {
        [DllImport("c_wrapper.dll", EntryPoint = "create_proxy_options_instance")]
        private static extern int create_proxy_options_instance(ref IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "destroy_proxy_options_instance")]
        private static extern void destroy_proxy_options_instance(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "copy_proxy_options_instance")]
        private static extern void copy_proxy_options_instance(IntPtr srcinstance, IntPtr dstinstance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_proxy_options_type")]
        private static extern int get_proxy_options_type(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_proxy_options_port")]
        private static extern int get_proxy_options_port(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_proxy_options_address")]
        private static extern IntPtr get_proxy_options_address(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_proxy_options_user_name")]
        private static extern IntPtr get_proxy_options_user_name(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_proxy_options_password")]
        private static extern IntPtr get_proxy_options_password(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "set_proxy_options_type")]
        private static extern void set_proxy_options_type(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_proxy_options_port")]
        private static extern void set_proxy_options_port(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_proxy_options_address")]
        private static extern void set_proxy_options_address(IntPtr instance, String value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_proxy_options_user_name")]
        private static extern void set_proxy_options_user_name(IntPtr instance, String value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_proxy_options_password")]
        private static extern void set_proxy_options_password(IntPtr instance, String value);

        private IntPtr native_instance_;

        public ProxyOptions()
        {
            create_proxy_options_instance(ref native_instance_);
        }

        ~ProxyOptions()
        {
            destroy_proxy_options_instance(native_instance_);
        }

        internal IntPtr NativeInstance
        {
            get { return native_instance_; }
            set { native_instance_ = value; }
        }

        internal void CopyNativeInstance(IntPtr native_instance)
        {
            copy_proxy_options_instance(native_instance, native_instance_);
        }

        public LMProxyType Type
        {
            get { return (LMProxyType)get_proxy_options_type(native_instance_); }
            set { set_proxy_options_type(native_instance_, (int)value); }
        }

        public int ProxyPort
        {
            get { return get_proxy_options_port(native_instance_); }
            set { set_proxy_options_port(native_instance_, value); }
        }

        public String ProxyAddress
        {
            get { return Marshal.PtrToStringAnsi(get_proxy_options_address(native_instance_)); }
            set { set_proxy_options_address(native_instance_, value); }
        }

        public String ProxyUserName
        {
            get { return Marshal.PtrToStringAnsi(get_proxy_options_user_name(native_instance_)); }
            set { set_proxy_options_user_name(native_instance_, value); }
        }

        public String ProxyPSW
        {
            get { return Marshal.PtrToStringAnsi(get_proxy_options_password(native_instance_)); }
            set { set_proxy_options_password(native_instance_, value); }
        }
    }

    public class VideoConfig
    {
        [DllImport("c_wrapper.dll", EntryPoint = "create_video_config_instance")]
        private static extern int create_video_config_instance(ref IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "destroy_video_config_instance")]
        private static extern void destroy_video_config_instance(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "copy_video_config_instance")]
        private static extern void copy_video_config_instance(IntPtr srcinstance, IntPtr dstinstance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_capture_width")]
        private static extern int get_video_config_capture_width(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_capture_height")]
        private static extern int get_video_config_capture_height(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_encode_width")]
        private static extern int get_video_config_encode_width(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_enocde_height")]
        private static extern int get_video_config_enocde_height(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_rotation")]
        private static extern int get_video_config_rotation(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_capture_fps")]
        private static extern int get_video_config_capture_fps(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_encode_fps")]
        private static extern int get_video_config_encode_fps(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_encode_bitrate")]
        private static extern int get_video_config_encode_bitrate(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_encode_qp")]
        private static extern int get_video_config_encode_qp(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_video_config_frame_interval")]
        private static extern int get_video_config_frame_interval(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_capture_width")]
        private static extern void set_video_config_capture_width(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_capture_height")]
        private static extern void set_video_config_capture_height(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_encode_width")]
        private static extern void set_video_config_encode_width(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_enocde_height")]
        private static extern void set_video_config_enocde_height(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_rotation")]
        private static extern void set_video_config_rotation(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_capture_fps")]
        private static extern void set_video_config_capture_fps(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_encode_fps")]
        private static extern void set_video_config_encode_fps(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_encode_bitrate")]
        private static extern void set_video_config_encode_bitrate(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_encode_qp")]
        private static extern void set_video_config_encode_qp(IntPtr instance, int value);
        [DllImport("c_wrapper.dll", EntryPoint = "set_video_config_frame_interval")]
        private static extern void set_video_config_frame_interval(IntPtr instance, int value);

        private IntPtr native_instance_;

        public VideoConfig()
        {
            create_video_config_instance(ref native_instance_);
        }

        ~VideoConfig()
        {
            destroy_video_config_instance(native_instance_);
        }

        internal IntPtr NativeInstance
        {
            get { return native_instance_; }
            set { native_instance_ = value; }
        }

        internal void CopyNativeInstance(IntPtr native_instance)
        {
            copy_video_config_instance(native_instance, native_instance_);
        }

        public int CaptureWidth
        {
            get { return get_video_config_capture_width(native_instance_); }
            set { set_video_config_capture_width(native_instance_, value); }
        }

        public int CaptureHeight
        {
            get { return get_video_config_capture_height(native_instance_); }
            set { set_video_config_capture_height(native_instance_, value); }
        }

        public int EncodeWidth
        {
            get { return get_video_config_encode_width(native_instance_); }
            set { set_video_config_encode_width(native_instance_, value); }
        }

        public int EncodeHeight
        {
            get { return get_video_config_enocde_height(native_instance_); }
            set { set_video_config_enocde_height(native_instance_, value); }
        }

        public int Rotation
        {
            get { return get_video_config_rotation(native_instance_); }
            set { set_video_config_rotation(native_instance_, value); }
        }

        public int CaptureFPS
        {
            get { return get_video_config_capture_fps(native_instance_); }
            set { set_video_config_capture_fps(native_instance_, value); }
        }

        public int EncodeFPS
        {
            get { return get_video_config_encode_fps(native_instance_); }
            set { set_video_config_encode_fps(native_instance_, value); }
        }

        public int EncodeBitrate
        {
            get { return get_video_config_encode_bitrate(native_instance_); }
            set { set_video_config_encode_bitrate(native_instance_, value); }
        }

        public int EncodeQP
        {
            get { return get_video_config_encode_qp(native_instance_); }
            set { set_video_config_encode_qp(native_instance_, value); }
        }

        public int FrameInterval
        {
            get { return get_video_config_frame_interval(native_instance_); }
            set { set_video_config_frame_interval(native_instance_, value); }
        }
    }

    public class PerMonitor
    {
        [DllImport("c_wrapper.dll", EntryPoint = "create_per_monitor_instance")]
        private static extern int create_per_monitor_instance(ref IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "destroy_per_monitor_instance")]
        private static extern void destroy_per_monitor_instance(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "copy_per_monitor_instance")]
        private static extern void copy_per_monitor_instance(IntPtr srcinstance, IntPtr dstinstance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_per_monitor_send_rate_mbps")]
        private static extern double get_per_monitor_send_rate_mbps(IntPtr instance);
        [DllImport("c_wrapper.dll", EntryPoint = "get_per_monitor_recv_rate_mbps")]
        private static extern double get_per_monitor_recv_rate_mbps(IntPtr instance);

        private IntPtr native_instance_;

        public PerMonitor()
        {
            create_per_monitor_instance(ref native_instance_);
        }

        ~PerMonitor()
        {
            destroy_per_monitor_instance(native_instance_);
        }

        internal IntPtr NativeInstance
        {
            get { return native_instance_; }
            set { native_instance_ = value; }
        }

        internal void CopyNativeInstance(IntPtr native_instance)
        {
            copy_per_monitor_instance(native_instance, native_instance_);
        }

        public double MbpsSendRate
        {
            get { return get_per_monitor_send_rate_mbps(native_instance_); }
        }

        public double MbpsRecvRate
        {
            get { return get_per_monitor_recv_rate_mbps(native_instance_); }
        }
    }
}
